/**
 * 
 */
package co.fitstart.payment.entity.request;

import java.util.Date;

import org.apache.http.client.utils.DateUtils;

import co.fitstart.payment.entity.app.App;
import co.fitstart.payment.entity.channel.Channel;
import co.fitstart.payment.entity.transaction.TransactionRecord;

/**
 * 退款请求记录
 * 
 * @author lute
 *
 */
public class RefundRecord {

    private Long id;
    
    private Long appId;
    
    private Long channelId;
    
    private Long transactionRecordId;
    
    /** 退款请求号 */
    private String refundNo;
    
    /** 交易机构退款单号 */
    private String refundId;
    
    /** 退款订单业务订单号，若为批量退款，此字段可为空 */
    private String orderNo;
    
    /** 订单总金额，若为批量退款，此字段可为空 */
    private int totalAmount;
    
    /** 退款总金额，若为批量退款，此字段可为空 */ 
    private int refundAmount;
    
    /** 是否为批量退款 */
    private boolean batch;
    
    /** 批量退款数据集，如批量退款为 {@code true} ，此字段不能为空 */
    private String batchData;
    
    /** App 回调 URL */
    private String notifyUrl;
    
    /** 退款请求时间 */
    private Date refundTime;
    
    /** 是否退款成功  */
    private boolean finished;
    
    private boolean disabled;
    
    /**
     * Default constructor
     */
    public RefundRecord() {
        
    }

    /**
     * @param app
     * @param channel
     * @param transactionRecord
     * @param orderNo
     * @param totalAmount
     * @param refundAmount
     * @param notifyUrl
     */
    public RefundRecord(App app, Channel channel, TransactionRecord transactionRecord, String orderNo, int totalAmount, int refundAmount, String notifyUrl) {
        this.appId = app.getId();
        this.channelId = channel.getId();
        this.transactionRecordId = transactionRecord.getId();
        this.orderNo = orderNo;
        this.totalAmount = totalAmount;
        this.refundAmount = refundAmount;
        this.notifyUrl = notifyUrl;
        this.refundTime = new Date();
        this.refundNo = genRefundNo(app.getAppid(), channel.getName(), refundTime);
    }
    
    /**
     * Generate unique refund number according to app, channel and refund time
     * 
     * @param app
     * @param channel
     * @param refundTime
     * @return
     */
    private String genRefundNo(String appid, String channelName, Date refundTime) {
        // Get appid abbreviation: first character + last character of appid
        String appidAbbreviation = new StringBuilder()
                                        .append(appid.charAt(0))
                                        .append(appid.charAt(appid.length() - 1))
                                        .toString()
                                        .toUpperCase();
        
        // Get channel name abbreviation: first character + last character of appid
        String channelNameAbbreviation = new StringBuilder()
                                                .append(channelName.charAt(0))
                                                .append(channelName.charAt(channelName.length() - 1))
                                                .toString()
                                                .toUpperCase();
        
        // Generate refund number, 24 digits in total
        return new StringBuilder()
                    .append(DateUtils.formatDate(refundTime, "yyyyMMdd"))  // 8 digits date string
                    .append(DateUtils.formatDate(refundTime, "HHmmssSSS"))  // 9 digits time string
                    .append("0")  // 1 placeholder digits for possible usage
                    .append(String.format("%02d", Double.valueOf(Math.floor(Math.random() * 100)).intValue()))  // 2 random number between 0 (inclusive) and 100 (exclusive)
                    .append(appidAbbreviation)  // 2 digits appid abbreviation
                    .append(channelNameAbbreviation)  // 2 digits channel name abbreviation
                    .toString();
    }
    
    /**
     * Finish the refund
     * 
     * @param refundId
     * @return
     */
    public RefundRecord refund(String refundId) {
        this.refundId = refundId;
        this.finished = true;
        return this;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the appId
     */
    public Long getAppId() {
        return appId;
    }

    /**
     * @return the channelId
     */
    public Long getChannelId() {
        return channelId;
    }

    /**
     * @return the transactionRecordId
     */
    public Long getTransactionRecordId() {
        return transactionRecordId;
    }

    /**
     * @return the refundNo
     */
    public String getRefundNo() {
        return refundNo;
    }

    /**
     * @return the refundId
     */
    public String getRefundId() {
        return refundId;
    }

    /**
     * @return the orderNo
     */
    public String getOrderNo() {
        return orderNo;
    }

    /**
     * @return the totalAmount
     */
    public int getTotalAmount() {
        return totalAmount;
    }

    /**
     * @return the refundAmount
     */
    public int getRefundAmount() {
        return refundAmount;
    }

    /**
     * @return the batch
     */
    public boolean isBatch() {
        return batch;
    }

    /**
     * @return the batchData
     */
    public String getBatchData() {
        return batchData;
    }

    /**
     * @return the notifyUrl
     */
    public String getNotifyUrl() {
        return notifyUrl;
    }

    /**
     * @return the refundTime
     */
    public Date getRefundTime() {
        return refundTime;
    }

    /**
     * @return the finished
     */
    public boolean isFinished() {
        return finished;
    }

    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param appId the appId to set
     */
    public void setAppId(Long appId) {
        this.appId = appId;
    }

    /**
     * @param channelId the channelId to set
     */
    public void setChannelId(Long channelId) {
        this.channelId = channelId;
    }

    /**
     * @param transactionRecordId the transactionRecordId to set
     */
    public void setTransactionRecordId(Long transactionRecordId) {
        this.transactionRecordId = transactionRecordId;
    }

    /**
     * @param refundNo the refundNo to set
     */
    public void setRefundNo(String refundNo) {
        this.refundNo = refundNo;
    }

    /**
     * @param refundId the refundId to set
     */
    public void setRefundId(String refundId) {
        this.refundId = refundId;
    }

    /**
     * @param orderNo the orderNo to set
     */
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    /**
     * @param totalAmount the totalAmount to set
     */
    public void setTotalAmount(int totalAmount) {
        this.totalAmount = totalAmount;
    }

    /**
     * @param refundAmount the refundAmount to set
     */
    public void setRefundAmount(int refundAmount) {
        this.refundAmount = refundAmount;
    }

    /**
     * @param batch the batch to set
     */
    public void setBatch(boolean batch) {
        this.batch = batch;
    }

    /**
     * @param batchData the batchData to set
     */
    public void setBatchData(String batchData) {
        this.batchData = batchData;
    }

    /**
     * @param notifyUrl the notifyUrl to set
     */
    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    /**
     * @param refundTime the refundTime to set
     */
    public void setRefundTime(Date refundTime) {
        this.refundTime = refundTime;
    }

    /**
     * @param finished the finished to set
     */
    public void setFinished(boolean finished) {
        this.finished = finished;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

}
